
const glob = require('glob');
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const crypto = require('crypto');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = require('../../config.js');
const utils = require('./copyMonaco');

let entryDir = config.entryDir || 'src/vue/modules';// 入口目录
const htmlTplDir = 'src/tpl';// html模板目录
// 去掉最后的/
if (!entryDir.split('/').pop()) {
  entryDir = entryDir.substring(0, entryDir.length - 1);
}
const proFolder = 'pro';// 默认输出目录
const output = config.output || proFolder;// 输出目录
const rootFolder = '../../../';
module.exports = {
  config,
  dev: process.env.NODE_ENV === 'development', // 开发
  isElec: process.env.PROJECT === 'suanbanyun-elec', // 是否是桌面端
  dist: 'static/vue',
  consoleInfo(text) {
    console.log('');
    console.log('--------------------------------------');
    console.log(chalk.green(text));
    console.log('--------------------------------------');
    console.log('');
  },
  /**
   * 构建完成后处理方法
   */
  buildEnd() {
    this.hashMap();
    utils.src2monaco(); // 处理monaco资源路径
  },
  removeEntry(entrys) {
    entrys.forEach((entry) => {
      const dir = path.resolve(__dirname, rootFolder, `dist/${entry}`);
      if (fs.existsSync(dir)) {
        this.deleteFolder(dir);
        console.log(chalk.green(`${dir} 删除成功！`));
      }
    });
  },
  buildPublicPath(url) {
    // 处理首页的天气图片路径
    if (this.isElec && (url.includes('weather') || url.includes('swiperBanner'))) {
      return url.replace('static/vue', '..');
    }
    let publicPath = this.config.cdn || '';
    if (this.dev) {
      publicPath = '';
    } else if (!publicPath.endsWith('/')) {
      publicPath += '/';
    }
    return publicPath + url;
  },
  /**
     * 资源文件目录
     * @param {资源路径} url
     * @param {资源类型} type
     */
  buildAssetsUrl(url, type) {
    const assets = `${this.dist}/assets/${type}/[name].[hash:10].[ext]`;
    /* if (!this.dev && (url.includes('weather') || url.includes('swiperBanner'))) {
      assets = `../assets/${type}/[name].[hash:10].[ext]`;
    } */
    return assets;
  },
  buildEntry() {
    const entrys = this._buildEntry(config);
    const components = this._buildEntry(config.components);
    Object.keys(components).forEach((key) => {
      const info = components[key];
      components[`components/${key}`] = info;
      delete components[key];
    });
    return Object.assign(entrys, components);
  },
  /**
   * 自动构建入口文件
   */
  _buildEntry(_config) {
    const entrys = {};
    const _entryDir = _config.entryDir || entryDir; // 入口目录
    const _output = _config.output || output; // 输出目录
    // 动态读取入口
    const files = glob.sync(`${_entryDir}/*/index.js`);
    const _entrys = [];
    files.forEach((f) => {
      const folders = f.split('/');
      _entrys.push(folders[folders.length - 2]);
    });
    // 配置入口
    (_config.entry || _entrys).forEach((_entry) => {
      let entry = _entry;
      let file = `${_entryDir}/${entry}/index.js`;
      if (typeof _entry == 'object') {
        file = `${_entry.folder}/index.js`;
        // eslint-disable-next-line prefer-destructuring
        entry = _entry.entry;
      }
      if (fs.existsSync(path.resolve(__dirname, rootFolder, file))) {
        const configFile = path.resolve(__dirname, rootFolder, file.replace('index.js', 'config.json'));
        let __output = _output;
        if (fs.existsSync(configFile)) {
          const cfg = JSON.parse(fs.readFileSync(configFile, 'utf-8'));
          if (cfg.output && cfg.output.length > 0) {
            __output = cfg.output == entry ? '' : cfg.output.toLowerCase();
          }
        }
        // entrys[`${__output}/${entry}`] = `./${file}`;
        entrys[`${entry}`] = `./${file}`;
        this.entryPath[entry] = `${__output}/${entry}`;
      }
    });
    return entrys;
  },
  entryPath: {},
  /**
     * 构建extjs视图文件
     */
  buildViews() {
    if (config.view == false) return;

    // 写入的文件夹
    const writeDir = path.join(__dirname, rootFolder, 'dist');
    // 模板
    const tpl = fs.readFileSync(path.join(__dirname, '../', 'tpl/View.js'), 'utf8');
    config.entry.forEach((_entry) => {
      const entry = this.entryPath[_entry];
      if (!entry) return false;
      const classArray = entry.split('/');
      const xtype = classArray.join('.').toLowerCase();
      classArray[0] = classArray[0].toUpperCase();// 包名大写
      classArray.push('View');
      const className = classArray.join('.');
      // 替换模版文件中的内容
      const info = tpl.replace(/{class}/g, className).replace(/{xtype}/g, xtype).replace(/{entry}/g, entry);
      let viewPath = path.join(`${writeDir}/${entry}`);
      if (!fs.existsSync(viewPath)) {
        // fs.mkdirsSync(viewPath, { recursive: true });
        this.mkdirsSync(viewPath, { recursive: true });
      }
      if (this.dev) {
        viewPath += '/View.js';
      } else {
        const hash = crypto.createHash('md5').update(info).digest('hex').substr(0, 10);// MD5版本
        viewPath += `/View.${hash}.js`;
      }
      fs.writeFileSync(viewPath, info, {
        encoding: 'UTF-8',
      });
    });
  },
  // 递归创建目录 同步方法
  mkdirsSync(dirname) {
    if (fs.existsSync(dirname)) {
      return true;
    }
    if (this.mkdirsSync(path.dirname(dirname))) {
      fs.mkdirSync(dirname);
      return true;
    }
  },
  /**
     * 驼峰转-
     * @param {String} name
     */
  toLine(name) {
    return name.replace(/([A-Z])/g, '-$1').toLowerCase();
  },
  /**
   * 删除目录
   * @param {String} path 路径
   */
  deleteFolder(folder) {
    const me = this; let
      files = [];
    if (fs.existsSync(folder)) {
      files = fs.readdirSync(folder);
      files.forEach((file) => {
        const curPath = path.join(folder, file);
        if (fs.statSync(curPath).isDirectory()) { // recurse
          me.deleteFolder(curPath);
        } else { // delete file
          fs.unlinkSync(curPath);
        }
      });
      fs.rmdirSync(folder);
    }
  },
  /**
   * 构建html模板
   * @param {*} entrys 入口文件
   * @returns {Array}
   */
  buildHtmlTpl(entrys) {
    const files = glob.sync(`${htmlTplDir}/*/config.json`);
    const entryKeys = Object.keys(entrys);
    const tpls = [];
    files.forEach((file) => {
      // 读取配置文件
      const cfg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../../../', file), 'utf-8'));
      // 模板配置信息
      const htmlCfg = {
        template: path.resolve(__dirname, '../../../', file.replace('/config.json', '/index.html')),
        inject: false,
        filename: cfg.output,
        chunks: [],
        minify: true, // 不压缩
        cdn: this.dev ? '' : config.cdn || '',
        server: config.proxyServerUrl || '',
      };

      // 需要的配置信息
      if (cfg.configInfo) {
        htmlCfg[cfg.configInfo] = config[cfg.configInfo];
      }
      // 依赖的模块
      cfg.entry.forEach((key) => {
        entryKeys.forEach((entry) => {
          if (entry == key) {
            htmlCfg.chunks.push(entry);
          }
        });
      });
      if (htmlCfg.chunks.length > 0) {
        tpls.push(new HtmlWebpackPlugin(htmlCfg));
      }
    });
    return tpls;
  },
  hashMap() {
    if (config.hashMap == false) return;

    const hash = {};
    const dist = 'dist/';
    const files = glob.sync(`${dist}**/*`);

    for (let i = 0; i < files.length; i++) {
      const file = files[i].replace(dist, '');
      const paths = file.split('/');
      const hashName = paths.pop();

      if (hashName.includes('.') && !hashName.endsWith('.html')) {
        const name = hashName.replace(/[-.](\d|[a-z]){10}/, '');
        if (!file.startsWith('static/vue/') || ['index.js', 'index.css'].includes(name)) {
          hash[paths.concat([name]).join('/')] = paths.concat([hashName]).join('/');
        }
      }
    }

    // TODO 支持本地ext调试
    if (this.dev) {
      const extPath = 'src/ext/';
      const extFiles = glob.sync(`${extPath}**/*`);
      extFiles.forEach((file) => {
        file = file.replace(extPath, 'pro/');
        hash[file] = file;
      });
    }

    // 创建目录
    const dir = path.resolve(__dirname, rootFolder, 'dist', 'static/js');
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }
    // 内容
    let content = '';
    if (Object.keys(hash).length > 0) {
      content += `window.__online_info__ && (window.__online_info__.hash_map=Object.assign({}, window.__online_info__.hash_map,${JSON.stringify(hash)}));`;
    }
    // 增加复写样式
    const css = 'static/project/override.css';
    const cssFile = path.resolve(__dirname, '../../resourse/project', config.project, css);
    if (fs.existsSync(cssFile)) {
      const _dt = new Date().getTime();
      content += `
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.href = (window.__online_info__ && window.__online_info__.cdn || '') + '/${css}?${_dt}';
        document.getElementsByTagName('head')[0].appendChild(link);
      `;
    }
    content = `
      (function(){
        ${content}
      })()
    `;
    // 生成映射文件
    fs.writeFileSync(path.resolve(dir, 'hash-map-pro.js'), content, 'utf-8');
    console.log(chalk.gray('<<<<<< hashMap.js 构建完成 '));
  },
};
